package pluginUtils;

import java.util.ArrayList;



public class Polytope {

	
	
	
	private ArrayList<Vector4D> theVertices=new ArrayList<Vector4D>();
	
	private static double phi=(1+Math.sqrt(5))/2;
	private static double gamma=-1/phi;
	
	static final int permut[][]={{0,1,2,3},{0,2,3,1},{0,3,1,2},{1,0,3,2},{1,2,0,3},
			{1,3,2,0},{2,0,1,3},{2,1,3,0},{2,3,0,1},{3,0,2,1},{3,1,0,2},{3,2,1,0}};
	
	private Polytope(){}
	
	public static Polytope make335(){
		Polytope resu=new Polytope(); 
		for(int i=0;i<4;i++){
			double[] a={0,0,0,0}; 
			a[i]=1; 
			Vector4D victor=new Vector4D(a); 
			resu.theVertices.add(victor);
			a[i]=-1; 
			victor=new Vector4D(a); 
			resu.theVertices.add(victor); 
		}
		
		for(int i=0;i<16;i++){
			double[] a={0.5,0.5,0.5,0.5};
			int value=i; 
			for(int j=0;j<4;j++){
				if(value%2==0)a[j]=-0.5;
				value=value/2;
			}
			Vector4D victor=new Vector4D(a);
			resu.theVertices.add(victor); 
		}
		
		double a[]={phi/2,0.5,gamma/2,0};
		
		
		
		for(int i=0;i<2;i++){
			if(i==0)a[0]=phi/2; else a[0]=-phi/2;
			for(int j=0;j<2;j++){
				if(j==0) a[1]=0.5; else a[1]=-0.5;
				for(int k=0;k<2;k++){
					if(k==0) a[2]=gamma/2; else a[2]=-gamma/2;
					for(int m=0;m<12;m++){
						double b[]=new double[4];
						for(int n=0;n<4;n++) b[n]=a[permut[m][n]]; 
						Vector4D victor=new Vector4D(b);
						resu.theVertices.add(victor); 
					}
				}//k
			}//j
		}// i
		
		for(Vector4D tomtom: resu.theVertices){
			for(Vector4D nana: resu.theVertices){
				if(Vector4D.distance(tomtom, nana)<=1/phi)
					if(!tomtom.equals(nana)) tomtom.addVoisin(nana); 
					
			}//nana
		}// tomtom
		
	return resu; 	
	}
	
	public static Polytope make120cell(){
		Polytope resu=new Polytope(); 
		Vector4D victor; 
		for(int i=0;i<3;i++){
			for(int j=i+1;j<4;j++){
			double[] a={0,0,0,0}; 
			a[i]=2; 
			a[j]=2; 
			victor=new Vector4D(a); 
			resu.theVertices.add(victor);
			a[i]=-2; 
			victor=new Vector4D(a); 
			resu.theVertices.add(victor);
			a[j]=-2;  
			victor=new Vector4D(a); 
			resu.theVertices.add(victor);
			a[i]=2; 
			victor=new Vector4D(a); 
			resu.theVertices.add(victor);
			}
		}
	for(int i=0;i<4;i++){
		for(int j=0;j<16;j++){
			double a[]={1,1,1,1}; 
			a[i]=Math.sqrt(5);
			int val=j; 
			for(int k=0;k<4;k++){
				if(val%2==0) a[k]=-a[k]; 
				val=val/2; 
			}// k 
			victor=new Vector4D(a);
			resu.theVertices.add(victor);
		}//j
	}// i
	
	for(int i=0;i<4;i++){
		for(int j=0;j<16;j++){
			double a[]={phi,phi,phi,phi}; 
			a[i]=1/(phi*phi);
			int val=j; 
			for(int k=0;k<4;k++){
				if(val%2==0) a[k]=-a[k]; 
				val=val/2; 
			}// k 
			victor=new Vector4D(a);
			resu.theVertices.add(victor);
		}//j
	}// i
	for(int i=0;i<4;i++){
		for(int j=0;j<16;j++){
			double a[]={1/phi,1/phi,1/phi,1/phi}; 
			a[i]=phi*phi;
			int val=j; 
			for(int k=0;k<4;k++){
				if(val%2==0) a[k]=-a[k]; 
				val=val/2; 
			}// k 
			victor=new Vector4D(a);
			resu.theVertices.add(victor);
		}//j
	}// i
	
	double a[]={phi*phi,1/(phi*phi),1,0};
	for(int i=0;i<2;i++){
		if(i==0)a[0]=phi*phi; else a[0]=-phi*phi;
		for(int j=0;j<2;j++){
			if(j==0) a[1]=1/(phi*phi); else a[1]=-1/(phi*phi);
			for(int k=0;k<2;k++){
				if(k==0) a[2]=1; else a[2]=-1;
				for(int m=0;m<12;m++){
					double b[]=new double[4];
					for(int n=0;n<4;n++) b[n]=a[permut[m][n]]; 
					victor=new Vector4D(b);
					resu.theVertices.add(victor); 
				}
			}//k
		}//j
	}// i
	
	double[] aa={Math.sqrt(5),1/phi,phi,0};
	for(int i=0;i<2;i++){
		if(i==0)aa[0]=Math.sqrt(5); else aa[0]=-Math.sqrt(5);
		for(int j=0;j<2;j++){
			if(j==0) aa[1]=1/phi; else aa[1]=-1/phi;
			for(int k=0;k<2;k++){
				if(k==0) aa[2]=phi; else aa[2]=-phi;
				for(int m=0;m<12;m++){
					double b[]=new double[4];
					for(int n=0;n<4;n++) b[n]=aa[permut[m][n]]; 
					victor=new Vector4D(b);
					resu.theVertices.add(victor); 
				}
			}//k
		}//j
	}// i
	
		for(int i=0;i<16;i++){
		double ab[]={2,1,phi,1/phi};
		int val=i;
		for(int j=0;j<4;j++){
			if(val%2==0)ab[j]=-ab[j]; 
			val=val/2; 
		}//j
		for(int m=0;m<12;m++){
			double b[]=new double[4];
			for(int n=0;n<4;n++) b[n]=ab[permut[m][n]]; 
			victor=new Vector4D(b);
			resu.theVertices.add(victor); 
		}
		}//
		for(Vector4D tomtom: resu.theVertices){
			for(Vector4D nana: resu.theVertices){
				if(Vector4D.distance(tomtom, nana)<=1)
					if(!tomtom.equals(nana)) tomtom.addVoisin(nana); 
					
			}//nana
		}// tomtom
		
		
		return resu; 
	}
	
	
	
	public ArrayList<Vector4D> getVertices(){return this.theVertices; }
	

	public static void main(String[] args) {
		Polytope gege=make120cell();
		/*
		try{
			PrintStream outx=new PrintStream("/tmp/outgeode.txt");
			outx.println("toto"); 
		}
		catch (Exception e){System.out.println(e); }
		*/
		for(Vector4D bb:gege.theVertices) System.out.println(bb); 
		System.out.println("done "+gege.theVertices.size());
	}
}
